package org.Yiran.timetale_re.capability;

import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.CapabilityToken;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.common.util.LazyOptional;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * 符文制作熟练度能力提供者类
 * 实现了ICapabilityProvider和INBTSerializable接口，用于为玩家实体提供符文制作熟练度能力
 * <p>
 * 主要功能:
 * 1. 为玩家实体提供符文制作熟练度能力
 * 2. 管理能力实例的创建和访问
 * 3. 实现能力数据的序列化和反序列化
 */
public class RuneCraftingProficiencyProvider implements ICapabilityProvider, INBTSerializable<CompoundTag> {

    // ==================== 能力定义 ====================

    /**
     * 符文制作熟练度能力的Capability实例
     * 用于在Forge能力系统中注册和获取符文制作熟练度能力
     */
    public static Capability<RuneCraftingProficiency> RUNE_CRAFTING_PROFICIENCY =
        CapabilityManager.get(new CapabilityToken<>() {
        });

    // ==================== 实例变量 ====================

    /** 符文制作熟练度能力实例 */
    private RuneCraftingProficiency proficiency = null;

    /** 懒加载的符文制作熟练度能力可选实例 */
    private final LazyOptional<RuneCraftingProficiency> optional = LazyOptional.of(this::createProficiency);

    /** 玩家引用 */
    private Player player;

    // ==================== 玩家引用管理 ====================

    /**
     * 设置玩家引用
     * 当能力被附加到玩家时调用，确保能力实例能够访问到玩家对象
     *
     * @param player 玩家实体引用
     */
    public void setPlayer(Player player) {
        this.player = player;
        if (proficiency != null) {
            proficiency.setPlayer(player);
        }
    }

    // ==================== 能力实例创建 ====================

    /**
     * 创建符文制作熟练度能力实例
     * 使用懒加载模式，只有在需要时才创建实例
     *
     * @return 符文制作熟练度能力实例
     */
    private RuneCraftingProficiency createProficiency() {
        if (proficiency == null) {
            proficiency = new RuneCraftingProficiency();
            if (player != null) {
                proficiency.setPlayer(player);
            }
        }
        return proficiency;
    }

    // ==================== 能力提供接口实现 ====================

    /**
     * 获取指定类型的能力实例
     * 实现ICapabilityProvider接口的核心方法
     *
     * @param cap 请求的能力类型
     * @param side 请求的方向（可为空）
     * @param <T> 能力类型参数
     * @return 对应能力的懒加载可选实例，如果不匹配则返回空的可选实例
     */
    @Override
    public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
        // 如果请求的是符文制作熟练度能力，则返回该能力的可选实例
        if (cap == RUNE_CRAFTING_PROFICIENCY) {
            return optional.cast();
        }
        // 否则返回空的可选实例
        return LazyOptional.empty();
    }

    // ==================== NBT序列化接口实现 ====================

    /**
     * 将能力数据序列化为NBT标签
     * 实现INBTSerializable接口，用于保存能力数据到玩家数据中
     *
     * @return 包含能力数据的CompoundTag
     */
    @Override
    public CompoundTag serializeNBT() {
        CompoundTag tag = new CompoundTag();
        // 确保获取到实际的能力实例并序列化其数据
        tag.put("RuneCraftingProficiency", createProficiency().serializeNBT());
        return tag;
    }

    /**
     * 从NBT标签反序列化能力数据
     * 实现INBTSerializable接口，用于从玩家数据中恢复能力数据
     *
     * @param tag 包含能力数据的CompoundTag
     */
    @Override
    public void deserializeNBT(CompoundTag tag) {
        // 确保创建了能力实例后再反序列化数据
        if (tag.contains("RuneCraftingProficiency")) {
            createProficiency().deserializeNBT(tag.getCompound("RuneCraftingProficiency"));
        }
    }
}